﻿using System;
using System.Collections.Generic;
using com.yoozoo.gta.Gameplay.PVE;
using com.yoozoo.gta.Gameplay.PVE.Editor;
using Gameplay.PVE.Editor;
using UnityEditor;
using UnityEngine;
using Yoozoo.Core.Extensions.Engine;
using Yoozoo.Framework.Managers;
using Yoozoo.Gta.Common;
using Yoozoo.UI.YGUI;

namespace Gameplay.PVE
{
    public class SceneMapCreator
    {
        private static GameObject root;
      
        //[MenuItem("GTATools/GamePlay/PVE/Step2:GenerateSceneDisplay")]
        public static void CreateMap(string mapConfigName,SceneSeparateManager separateManager)
        {
            
            var mapPath = "Assets/ResourcesAssets/Pve/Scene/" + mapConfigName + ".asset";
            var mapData = AssetDatabase.LoadAssetAtPath<GgameSceneConfig>(mapPath);
            if (mapData == null)
            {
                Debug.LogError("未找到 "+mapPath);
                return;
            }
            
            GameObject rootObj;
            root = separateManager.gameObject;
            rootObj = new GameObject("Root Tile");
            rootObj.transform.SetParent(root.transform);
           
            if (mapData != null)
            {
                for (int i = 0; i < mapData.PrefabDatas.Count; i++)
                {
                    var obj = mapData.PrefabDatas[i];

                    string resPath = mapData.GetPrefabResPath(obj);
                    
                    if (string.IsNullOrEmpty(resPath))
                    {
                        continue;
                    }

                    GameObject origin = AssetDatabase.LoadAssetAtPath<GameObject>(resPath);
                    if (!origin)
                    {
                        EditorUtility.DisplayDialog("错误", "找不到这个预设体："+resPath, "关闭");
                        continue;
                    }
                    
                    var prefab = GameObject.Instantiate(origin);
                    var sdb = prefab.AddComponent<ScceneDataBind>();
                    sdb.Index = i;
                    var objectBinder = prefab.transform.GetComponent<SceneObjectBinder>();
                    if (objectBinder)
                    {
                        sdb.ObjType = objectBinder.ObjectType;
                        sdb.IsNavMesh = objectBinder.IsNavMesh;
                    }
                    else
                    {
                        sdb.ObjType = SceneObjType.Dynamic;
                        sdb.IsNavMesh = false;
                    }

                    PrefabMeshRenderCache meshRenderCache = prefab.GetComponent<PrefabMeshRenderCache>();
                    if (meshRenderCache && obj.MeshRendererDatas!=null)
                    {
                        for (int j = 0; j < meshRenderCache.MeshRenderers.Count; j++)
                        {
                            if (j < obj.MeshRendererDatas.Count)
                            {
                                meshRenderCache.MeshRenderers[j].lightmapIndex = obj.MeshRendererDatas[j].lightmapIndex;
                                meshRenderCache.MeshRenderers[j].lightmapScaleOffset = obj.MeshRendererDatas[j].lightmapScaleOffset;
                            }
                            else
                            {
                                //EditorUtility.DisplayDialog("错误", "MeshRender的信息与其数量不一致："+resPath, "关闭");
                            }
                        }
                    }

                    prefab.transform.position = obj.position;
                    prefab.transform.localScale = obj.scale;
                    prefab.transform.eulerAngles = obj.rotation;
                    prefab.transform.SetParent(rootObj.transform);
                    prefab.name = prefab.name;
                }
            }
        }

        [MenuItem("GTATools/GamePlay/PVE/对象池使用情况")]
        public static void LogPoolInfo()
        {
            ResidentHandler.Inst.GetFunction("L_RpgManager.LogPoolInfo").Call();
        }
        
        [MenuItem("GTATools/GamePlay/PVE/最新rpg场景导出")]
        public static void RpgSceneGenerator()
        {
            EditorWindow.GetWindow<RpgSceneGenerator>("编辑器", true);
        }
        
        [MenuItem("GTATools/GamePlay/PVE/全部场景出生点位检查(运行时）")]
        public static void CheckScene()
        {
            ResidentHandler.Inst.GetFunction("L_RpgManager.BornPositionCheck").Action();
        }
        
        [MenuItem("GameObject/Rpg/场景点位贴地检查")]
        public static void CheckBluePrintPointAttachGround()
        {
            var gameObject = Selection.gameObjects[0];
            var transform = gameObject.transform;
            CheckChildAttachGround(transform,true);
        }

        private static void CheckChildAttachGround(Transform transform,bool showLog = false)
        {
            if (transform == null)
            {
                return;
            }

            if (transform.gameObject.name.Contains("fighting_"))
            {
                PveScene.CheckAttachGround(transform,showLog);
                return;
            }
            var childCount = transform.childCount;
            for (int i = 0; i < childCount; i++)
            {
                CheckChildAttachGround(transform.GetChild(i),showLog);
            }
        }

        
        
        [MenuItem("GameObject/Rpg/保存成rpg场景")]
        public static void SaveRpgScene()
        {
            var gameObject = Selection.gameObjects[0];
            var rpgSceneData = gameObject.GetComponent<RpgBattleSceneData>();
            if (rpgSceneData)
            {
                var path = "Assets/ResourcesAssets/Pve/Prefabs/Others/" + rpgSceneData.name + ".prefab";
                if (EditorUtility.DisplayDialog("提示", "将会覆盖" + path + "，是否继续？", "确定", "取消"))
                {
                    Editor.RpgSceneGenerator.SaveScene(rpgSceneData,path);
                }
            }
            else
            {
                EditorUtility.DisplayDialog("提示","没有找到RpgBattleSceneData","确定");
            }
            
        }
        
        [MenuItem("GameObject/Rpg/text")]
        public static void TextTest()
        {
            var gameObject = Selection.gameObjects[0];
            PveScene.ResizeTextWithFixedWidthAndLine(gameObject.GetComponent<RectTransform>(),313,3);
        }
        
        [MenuItem("GameObject/Rpg/text2")]
        public static void TextTest2()
        {
            var gameObject = Selection.gameObjects[0];
            PveScene.ResizeTextWidthMaxWidth(gameObject.GetComponent<RectTransform>(),300);
        }
        
        [MenuItem("GameObject/Rpg/text5")]
        public static void TextTest6()
        {
            var gameObject = Selection.gameObjects[0];
            YText.RefreshTextHeightBestFit(gameObject.GetComponent<YText>());
        }
        
        

        [MenuItem("GameObject/Rpg/text3")]
        public static void TextTest3()
        {
            var gameObject = Selection.gameObjects[0];
            var rpgFlyTextBuff = gameObject.GetComponent<RpgFlyTextBuff>();
            if (rpgFlyTextBuff)
            {
                rpgFlyTextBuff.SetText(rpgFlyTextBuff.tmp.text,70);
            }
        }
        
        [MenuItem("GameObject/Rpg/text4")]
        public static void TextTest4()
        {
            var gameObject = Selection.gameObjects[0];
            var rpgBubbleSizeFitter = gameObject.GetComponent<RpgBubbleSizeFitter>();
            if (rpgBubbleSizeFitter)
            {
                rpgBubbleSizeFitter.Resize();
            }
        }
       
        [MenuItem("GameObject/Rpg/textCritical")]
        public static void TextTestCritical()
        {
            var gameObject = Selection.gameObjects[0];
            var rpgFlyTextBuff = gameObject.GetComponent<RpgFlyTextBuff>();
            if (rpgFlyTextBuff)
            {
                rpgFlyTextBuff.SetTextCritical(rpgFlyTextBuff.tmp.text);
            }
        }
        [MenuItem("GameObject/Rpg/textBuff")]
        public static void TextTestBuff()
        {
            var gameObject = Selection.gameObjects[0];
            var rpgFlyTextBuff = gameObject.GetComponent<RpgFlyTextBuff>();
            if (rpgFlyTextBuff)
            {
                rpgFlyTextBuff.SetTextBuff(rpgFlyTextBuff.tmp.text,70);
            }
        }
        
        
        [MenuItem("GTATools/GamePlay/PVE/CubeMesh")]
        public static void CreateCubeMesh()
        {
            var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
            var meshFilter = cube.GetComponent<MeshFilter>();
            var cubeMesh = meshFilter.sharedMesh;
            var newMesh = new Mesh();
            var vertices = new Vector3[cubeMesh.vertices.Length];
            var triangles = new int[cubeMesh.triangles.Length - 6];
            var uv = new Vector2[cubeMesh.uv.Length];
            int index = 0;
            for (int i = 0; i < cubeMesh.vertices.Length; i++)
            {
                /*if (i < 4)//cubeMesh.vertices.Length - 4)
                {
                    continue;
                }*/
                vertices[index] = cubeMesh.vertices[i];
                index++;
            }

            index = 0;
            int a = 4;
            for (int i = 0; i < cubeMesh.triangles.Length; i++)
            {
                if (cubeMesh.triangles[i] < 4 * (a + 1) && cubeMesh.triangles[i] >= 4 * a)
                {
                    continue;
                }
                triangles[index] = cubeMesh.triangles[i];
                index++;
            }
            
            index = 0;
            for (int i = 0; i < cubeMesh.uv.Length; i++)
            {
                /*if (i < 4)//(i >= cubeMesh.uv.Length - 4)
                {
                    continue;
                }*/
                uv[index] = cubeMesh.uv[i];
                index++;
            }

            newMesh.vertices = vertices;
            newMesh.triangles = triangles;
            newMesh.uv = uv;
            meshFilter.mesh = newMesh;
            AssetDatabase.CreateAsset(newMesh,"Assets/Arts/Effect/BattleEffect/Model/mesh_cube_minus_one_side.asset");
        }

        [MenuItem("GameObject/Rpg/预览战场")]
        public static void PreviewBattlePoint()
        {
            var scenePrefabs = GameObject.FindObjectsOfType<RpgBattleSceneData>();
            GameObject root = null;
            for (int i = 0; i < scenePrefabs.Length; i++)
            {
                var go = scenePrefabs[i].gameObject;
                if (go.name == "battle")
                {
                    root = go;
                }
                else
                {
                    GameObject.DestroyImmediate(go);
                }
            }

            if (root != null)
            {
                var parent = Selection.activeGameObject.transform;
                var newObject = GameObject.Instantiate(root,parent);
                var sceneData = newObject.GetComponent<RpgBattleSceneData>();
                newObject.transform.localPosition = Vector3.zero;//sceneData.position;
                newObject.transform.localEulerAngles = Vector3.zero;//sceneData.rotation;
                newObject.name = "[TemplateBattlePoint]";
            }
        }
        
        [MenuItem("GameObject/Rpg/自动创建战场点位")]
        public static void AutoCreateBattlePoint()
        {
            var root = Selection.activeGameObject;
            if (root.name == "BlueprintPointRoot")
            {
                var prefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(root);
                PrefabUtility.UnpackPrefabInstance(root,PrefabUnpackMode.Completely,InteractionMode.AutomatedAction);
                var hangingRoot = root.transform.Find("Hanging");
                Dictionary<string, int> dic = new Dictionary<string, int>();//key = levelId,value = order
                Dictionary<string, GameObject> dic2 = new Dictionary<string, GameObject>();
                for (int i = 0; i < hangingRoot.childCount; i++)
                {
                    var point = hangingRoot.GetChild(i);
                    var str = point.name.Split('_');
                    if (str.Length == 2 && point.name.Contains("battle_"))
                    {
                        //是战斗点位
                        var levelId = str[1];
                        var fightingPointName = "fighting_" + levelId;
                        if (!hangingRoot.Find(fightingPointName))
                        {
                            var gameObject = GameObject.Instantiate(point.gameObject);
                            gameObject.transform.localScale = Vector3.one;
                            gameObject.name = fightingPointName;
                            dic.Add(levelId,i+1);
                            dic2.Add(levelId,gameObject);
                        }
                    }
                }

                int offset = 0;
                foreach (var item in dic2)
                {
                    item.Value.transform.SetParent(hangingRoot);
                    item.Value.transform.SetSiblingIndex(dic[item.Key] + offset);
                    offset++;
                }
                PrefabUtility.SaveAsPrefabAsset(root, prefabPath);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }
        }
        
        [MenuItem("GameObject/Rpg/自动创建退出点位")]
        public static void AutoCreateExitPoint()
        {
            var root = Selection.activeGameObject;
            if (root.name == "BlueprintPointRoot")
            {
                var prefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(root);
                PrefabUtility.UnpackPrefabInstance(root,PrefabUnpackMode.Completely,InteractionMode.AutomatedAction);
                var hangingRoot = root.transform.Find("Hanging");
                Dictionary<string, int> dic = new Dictionary<string, int>();//key = levelId,value = order
                Dictionary<string, GameObject> dic2 = new Dictionary<string, GameObject>();
                for (int i = 0; i < hangingRoot.childCount; i++)
                {
                    var point = hangingRoot.GetChild(i);
                    var str = point.name.Split('_');
                    if (str.Length == 2 && point.name.Contains("battle_"))
                    {
                        //是战斗点位
                        var levelId = str[1];
                        var fightingPointName = "exitpoint_" + levelId;
                        if (!hangingRoot.Find(fightingPointName))
                        {
                            var gameObject = GameObject.Instantiate(point.gameObject);
                            gameObject.transform.localScale = Vector3.one;
                            gameObject.name = fightingPointName;
                            dic.Add(levelId,i+1);
                            dic2.Add(levelId,gameObject);
                        }
                    }
                }

                int offset = 0;
                foreach (var item in dic2)
                {
                    item.Value.transform.SetParent(hangingRoot);
                    item.Value.transform.SetSiblingIndex(dic[item.Key] + offset);
                    offset++;
                }
                PrefabUtility.SaveAsPrefabAsset(root, prefabPath);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }
        }
        
        [MenuItem("GameObject/Rpg/查看总共有多少孩子节点")]
        public static void ShowChildCount()
        {
            var root = Selection.activeGameObject;
            var childCount = GetChildCount(root.transform);
            Debug.LogError("孩子数量" + childCount);
        }

        private static int GetChildCount(Transform transform)
        {
            var count = 1;
            for (int i = 0; i < transform.childCount; i++)
            {
                var child = transform.GetChild(i);
                count += GetChildCount(child);
            }
            return count;
        }
        
        [MenuItem("GameObject/Rpg/场景prefab还原成显示模式")]
        public static void TurnBackScenePrefab()
        {
            var root = Selection.activeGameObject;
            var sceneData = root.GetComponent<RpgBattleSceneData>();
            if (sceneData)
            {
                try
                {
                    PrefabUtility.UnpackPrefabInstance(sceneData.gameObject, PrefabUnpackMode.OutermostRoot,
                        InteractionMode.AutomatedAction);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    throw;
                }
                finally
                {
                    var rootTrans = root.transform;
                    //还原相机
                    var deckCamera = rootTrans.Find("DeckCamera");
                    if (deckCamera)
                    {
                        deckCamera.gameObject.SetActive(true);
                    }

                    var camera = rootTrans.Find("Camera");
                    if (camera)
                    {
                        camera.gameObject.SetActive(true);
                    }

                    
                    //还原人物
                    var unitRoot = rootTrans.Find("[Units]");
                    if (unitRoot == null)
                    {
                        unitRoot = new GameObject("[Units]").transform;
                        unitRoot.SetParent(rootTrans);
                    }

                    var self = unitRoot.Find("0");
                    if (self == null)
                    {
                        self = new GameObject("0").transform;
                        self.SetParent(unitRoot);   
                    }
                    var enemy = unitRoot.Find("2");
                    if (enemy == null)
                    {
                        enemy = new GameObject("2").transform;
                        enemy.SetParent(unitRoot);
                    }

                    unitRoot.transform.localPosition = Vector3.zero;
                    unitRoot.transform.localEulerAngles = Vector3.zero;
                    
                    var modelPath = "Assets/Arts/Character/Role/hero/HERO_LeadMan/RPG/Prefabs/HERO_LeadMan_RPG.prefab";
                    var template = AssetDatabase.LoadAssetAtPath<GameObject>(modelPath);
                    for (int i = 0; i < sceneData.selfPositions.Count; i++)
                    {
                        Transform child;
                        if (i < self.childCount)
                        {
                            child = self.GetChild(i);
                        }
                        else
                        {
                            child = new GameObject("Place" + i).transform;
                            child.SetParent(self);
                            var gameObject = GameObject.Instantiate(template);
                            gameObject.transform.SetParent(child);
                            gameObject.transform.localPosition = Vector3.zero;
                            gameObject.transform.localEulerAngles = Vector3.zero;
                            gameObject.transform.localScale = Vector3.one;
                        }
                        child.position = sceneData.selfPositions[i];
                        child.forward = sceneData.battleForward;
                    }

                    var assist = new GameObject("Place Assist");
                    assist.transform.SetParent(self);
                    assist.transform.position = sceneData.selfAssistPosition;
                    var go = GameObject.Instantiate(template);
                    go.transform.SetParent(assist.transform);
                    go.transform.localPosition = Vector3.zero;
                    go.transform.localEulerAngles = Vector3.zero;
                    go.transform.localScale = Vector3.one;
                   
                    
                    for (int i = 0; i < sceneData.enemyPositions.Count; i++)
                    {
                        Transform child;
                        if (i < enemy.childCount)
                        {
                            child = enemy.GetChild(i);
                        }
                        else
                        {
                            child = new GameObject("Place" + i).transform;
                            child.SetParent(enemy);
                            var gameObject = GameObject.Instantiate(template);
                            gameObject.transform.SetParent(child);
                            gameObject.transform.localPosition = Vector3.zero;
                            gameObject.transform.localEulerAngles = Vector3.zero;
                            gameObject.transform.localScale = Vector3.one;
                        }
                        child.position = sceneData.enemyPositions[i];
                        child.forward = -sceneData.battleForward;
                    }
                    
                    assist = new GameObject("Place Assist");
                    assist.transform.SetParent(enemy);
                    assist.transform.position = sceneData.enemyAssistPosition;
                    go = GameObject.Instantiate(template);
                    go.transform.SetParent(assist.transform);
                    go.transform.localPosition = Vector3.zero;
                    go.transform.localEulerAngles = Vector3.zero;
                    go.transform.localScale = Vector3.one;
                }
            }
        }
    }
    
   
    

    [CustomEditor(typeof(BattleSceneLandscapeRegion))]
    [CanEditMultipleObjects]
    public class BattleSceneLandscapeRegionInspector : UnityEditor.Editor
    {
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();
            if (GUILayout.Button("生成地图"))
            {
                (target as BattleSceneLandscapeRegion).CopyFromScene();
            }
        }
    }
    
    [CustomEditor(typeof(BattleSceneUnits))]
    [CanEditMultipleObjects]
    public class BattleSceneUnitsInspector : UnityEditor.Editor
    {
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();
            if (GUILayout.Button("创建单位"))
            {
                var sceneData = FindObjectOfType<RpgBattleSceneData>();
                if (sceneData)
                {
                    var prefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(sceneData.gameObject);
                    PrefabUtility.UnpackPrefabInstance(sceneData.gameObject,PrefabUnpackMode.Completely,InteractionMode.AutomatedAction);
                    var unit = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/ResourcesAssets/Pve/Prefabs/Hero/HERO_Lead_AR_M.prefab");
                    var root = (target as BattleSceneUnits).transform;
                    var selfRoot = root.Find("0");
                    if (selfRoot != null)
                    {
                        GameObject.DestroyImmediate(selfRoot.gameObject);
                    }
                    selfRoot = new GameObject("0").transform;
                    selfRoot.forward = sceneData.battleForward;
                    selfRoot.SetParent(root);
                    
                    for (int i = 0; i < sceneData.selfPositions.Count; i++)
                    {
                        var newChild = GameObject.Instantiate(unit, selfRoot);
                        newChild.transform.position = sceneData.selfPositions[i];
                    }
                    var enemyRoot = root.Find("2");
                    if (enemyRoot != null)
                    {
                        GameObject.DestroyImmediate(enemyRoot.gameObject);
                    }
                    enemyRoot = new GameObject("2").transform;
                    enemyRoot.forward = -sceneData.battleForward;
                    enemyRoot.SetParent(root);
                    
                    for (int i = 0; i < sceneData.selfPositions.Count; i++)
                    {
                        var newChild = GameObject.Instantiate(unit, enemyRoot);
                        newChild.transform.position = sceneData.enemyPositions[i];
                    }
                    
                    PrefabUtility.SaveAsPrefabAsset(sceneData.gameObject, prefabPath);
                }
            }
        }
    }

    [CustomEditor(typeof(RenderSceneLight))]
    public class RenderSceneLightEditor : UnityEditor.Editor
    {
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();
            if (GUILayout.Button("保存背身视角光源"))
            {
                (target as RenderSceneLight).SaveOffsetBack();
            }
            else if (GUILayout.Button("保存普通视角光源"))
            {
                (target as RenderSceneLight).SaveOffsetNormal();
            }
        }
    }
    
}



